using System.Collections.Generic;
using System.ComponentModel.Composition;
using Caliburn.Micro;
using MediaOwl.Common;
using MediaOwl.Common.Messages;
using MediaOwl.Common.ScreenManagement;
using MediaOwl.Common.ViewModels;
using MediaOwl.LastFm.Data;
using MediaOwl.LastFm.Model;
using MediaOwl.LastFm.Resources;

namespace MediaOwl.LastFm.ViewModels
{
    [Export, PartCreationPolicy(CreationPolicy.NonShared)]
    public class MusicAlbumSingleViewModel : Workitem<LastFmViewModel>
    {
        #region Fields
        private readonly ILastFmDataRepository repository;
        private readonly IEventAggregator eventAggregator;
        #endregion

        #region Constructor

        [ImportingConstructor]
        public MusicAlbumSingleViewModel(ILastFmDataRepository repository, IEventAggregator eventAggregator)
        {
            this.repository = repository;
            this.eventAggregator = eventAggregator;
        }

        #endregion

        #region Properties & Backingfields

        private Album currentAlbum;
        public Album CurrentAlbum
        {
            get { return currentAlbum; }
            set
            {
                currentAlbum = value;
                NotifyOfPropertyChange(() => CurrentAlbum);
            }
        }

        public IList<Tag> Tags
        {
            get { return CurrentAlbum == null ? null : CurrentAlbum.Tags; }
        }
        public IList<Track> Tracks
        {
            get { return CurrentAlbum == null ? null : CurrentAlbum.Tracks; }
        }

        public bool CanShowArtist
        {
            get
            {
                if (CurrentAlbum == null)
                    return false;
                return !string.IsNullOrEmpty(CurrentAlbum.ArtistName);
            }
        }

        #endregion

        #region Methods

        public void WithAlbum(Album album)
        {
            if (album == null)
                return;
            DisplayName = album.Name;
            Run.Coroutine(FetchInfo(album));
        }

        public IEnumerator<IResult> FetchInfo(Album album)
        {
            yield return Show.Busy(this);

            yield return repository.GetAlbum(album, x => CurrentAlbum = x, x => eventAggregator.Publish(new ErrorMessage(x)));

            NotifyOfPropertyChange(() => Tags);
            NotifyOfPropertyChange(() => Tracks);
            NotifyOfPropertyChange(() => CanShowArtist);

            yield return Show.NotBusy(this);
        }

        public IEnumerator<IResult> ShowArtist()
        {
            yield return Show.Busy(this);
            Artist tempArtist = null;
            yield return repository.GetArtist(CurrentAlbum.ArtistName, false, x => tempArtist = x, x => eventAggregator.Publish(new ErrorMessage(x)));
            yield return Show.NotBusy(this);
            if (tempArtist != null)
            {
                yield return Show.Child<MusicArtistSingleViewModel>(Helper.GetScreenId(tempArtist))
                .In(Parent)
                .Configured(x => x.WithArtist(tempArtist));
            }
        }

        public IEnumerator<IResult> OpenPicture()
        {
            yield return Show.Busy(this);
            yield return Show.Child<ShowPictureSingleViewModel>(Helper.GetScreenId(CurrentAlbum.PictureLarge))
                .In(Parent)
                .Configured(x => x.WithPicture(CurrentAlbum.PictureLarge, string.Format(Captions.PictureTitle, CurrentAlbum.Name)));
            yield return Show.NotBusy(this);
        }

        public IEnumerator<IResult> OpenTrack(object track)
        {
            if (track is Track)
            {
                yield return Show.Child<MusicTrackSingleViewModel>(Helper.GetScreenId((Track)track))
                    .In(Parent)
                    .Configured(x => x.WithTrack((Track)track));
            }
        }

        public IEnumerator<IResult> OpenTag(object selectedItem)
        {
            if (selectedItem is Tag)
            {
                yield return Show.Child<MusicTagSingleViewModel>(Helper.GetScreenId((Tag)selectedItem))
                    .In(Parent)
                    .Configured(x => x.WithTag((Tag)selectedItem));
            }
        }

        #endregion
    }
}